/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; Copyright (c) 2022 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "dma.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "bsp_lcd.h"
#include "bsp_ultrasonic.h"
#include "esp8266.h"
#include "bsp_delay.h"
#include "app_system.h"
#include "key.h"
#include "dht11.h"
void SystemClock_Config(void);

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
	void myDelay(int n)
{
  int i, j;
  for(i = 0; i < n; i++)
  {
    for(j = 0; j < 5; j++)
    {
      ;
    }
  }
}

void beep_init()
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};    
  GPIO_InitStruct.Pin = GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

	void beep(int freq, int ms)     //freq 频率   ms 声音播放时间
{
  int i;
  for(i = 0; i < ms * 1500 / freq / 2; i++)
  {
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7, GPIO_PIN_RESET);
    myDelay(freq * 2);
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7, GPIO_PIN_SET);
    myDelay(freq * 2);       
  }
}

int main(void)
{
  HAL_Init();
  SystemClock_Config();
	delay_init(64);
  MX_GPIO_Init();
	MX_DMA_Init();		//ADC数据读取用到了DMA
  MX_ADC1_Init();		//初始化ADC
	HAL_ADC_Start_DMA(&hadc1,(uint32_t*)ADC_DMA_Value,ADC_NUM);//开始转换ADC 	
  Lcd_Init();
  Lcd_Clear(YELLOW) ;
	KeyInit();             //按键的初始化已经写好了，
	beep_init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
	
  Gui_DrawFont_GBK16(0,32,BLACK,YELLOW,(uint8_t*)"SSID:");
		
  __HAL_UART_ENABLE_IT(&huart2, UART_IT_IDLE);	// 开启串口2的空闲中断
  __HAL_UART_CLEAR_IDLEFLAG(&huart2);  // 清空串口2的空闲中断状态
	// 开启串口2的DMA接收传输
  HAL_UART_Receive_DMA(&huart2,Usart2type.UsartDMARecBuffer,USART_DMA_REC_SIE);
	
	__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);		// 开启使用USART+DMA的方式接收串口的不定长数据
  __HAL_UART_CLEAR_IDLEFLAG(&huart1);
  HAL_UART_Receive_DMA(&huart1,Usart1type.UsartDMARecBuffer,USART_DMA_REC_SIE);
	
  initEsp8266(); //ESP8266_Init();	// 状态机初始化    ====>  连接网络
	FS_DHT11_Init(); //


	//
	//检测温湿度  然后 把温湿度 发给 网络调试助手
	Gui_DrawFont_GBK16(40,32,BLACK,YELLOW,(uint8_t*)WIFI_SSID);  //屏幕显示wifi名
	Gui_DrawFont_GBK16(0,48,BLACK,YELLOW,(uint8_t*)StationIPV4);   //屏幕显示IP地址
	char buf[20] = {0};     //定义一个buf 来存数据
	char buf1[20] = {0};
	char * menu[3] = {"LED1","LED2","FAN"};            //制作一个小灯的菜单
	int flag = 0;             //表示我当前的行数
	int status[3] = {0};      //status[0] 表示的是Led1 的状态  status[1] 表示的是Led2  status[2] 表示的是 风扇的状态
	while (1)
  {
		DHT11_Read_Data();         //读取数据
		if(ucharT_data_H != 0)
		{
			 sprintf(buf,"TH,%d.%d,%d.%d",ucharT_data_H,ucharT_data_L,ucharRH_data_H,ucharRH_data_L);
		}
		Gui_DrawFont_GBK16(0,0,BLACK,YELLOW,(uint8_t *)buf);
		//UART  串口   Transmit 发送
		HAL_UART_Transmit(&huart2,(uint8_t *)buf,sizeof(buf),10);  //串口2发送hello     一直发送hello
		//&huart2  串口
		//helle  内容
		//5      内容的大小
		//timeout   超时重连
		HAL_Delay(500);
		int light_Value =   AdSensor();             //获取光照值 
		sprintf(buf1,"light,%d",light_Value);        //拷贝到 buf 里面    光敏模块插入上，
		HAL_UART_Transmit(&huart2,(uint8_t *)buf1,sizeof(buf1),10);
		Gui_DrawFont_GBK16(0,16,BLACK,YELLOW,(uint8_t *)buf1);
		
		HAL_Delay(500);                          //每隔一秒就会发送一次
		if(Usart2type.UsartRecFlag)             //如果有接收到的数据，
		{
			
			Gui_DrawFont_GBK16(50,70, BLACK, YELLOW,Usart2type.UsartRecBuffer); //将接收数据显示到屏幕
			//网络调试助手发送  LED2ON  可以实现开灯   发送 LED2OFF  可以实现关灯
			
			if(strcmp(Usart2type.UsartRecBuffer,"LED1ON")== 0)
			{
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);
						
						
			}
			else if(strcmp(Usart2type.UsartRecBuffer,"LED1OFF")==0 )
			{
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);
			}
			
			if(strcmp(Usart2type.UsartRecBuffer,"LED2ON")== 0)
			{
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);
						
						
			}
			else if(strcmp(Usart2type.UsartRecBuffer,"LED2OFF")==0 )
			{
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);
			}
			
			if(strcmp(Usart2type.UsartRecBuffer,"FANON") == 0)
			{
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);   //开风扇
			}
			else if(strcmp(Usart2type.UsartRecBuffer,"FANOFF") == 0)
			{
						HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);    //关风扇
			}
			if(strcmp(Usart2type.UsartRecBuffer,"RELAYON") == 0)
			{
					HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);   //开继电器
			}
			else if(strcmp(Usart2type.UsartRecBuffer,"RELAYOFF") == 0)
			{
				HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);   //开继电器
			}
			if(strcmp(Usart2type.UsartRecBuffer,"BEEPON") == 0)
			{
				beep(494,1000);
			}
			else if(strcmp(Usart2type.UsartRecBuffer,"BEEPOFF") == 0)
			{
				
			}
			
			Usart2type.UsartRecLen = 0;            //长度 清零
			memset(Usart2type.UsartRecBuffer, 0, sizeof(Usart2type.UsartRecBuffer));    //缓冲区 清零
		 }	
		 int Key = GetKey();
		 delay_ms(20);       //延时消抖 
		 if(Key == KEY_UP)
		 {
				
				flag --;
				if(flag < 0)
						flag = 2;
			}
		 else if(Key == KEY_DOWN)
		 {
				flag ++;
				if(flag > 2)
					 flag  = 0;
		 }	 
		 else if(Key == KEY_SEL)
		 {
					if(flag == 0)       //选中的 Led1  
					{
								if(status[0])                   //如果状态为1的  关掉小灯
								{
										status[0] = 0;
										HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET);
								}
								else{                              //为零的话 开灯
											status[0] = 1;
											HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET);       //开灯
								}
					}
					else if(flag == 1)   //选中的是 Led2
					{
								if(status[1])                   //如果状态为1的  关掉小灯
								{
										status[1] = 0;
										HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);
								}
								else{                              //为零的话 开灯
										status[1] = 1;
										HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);       //开灯
								}
					}
					else if(flag == 2)   //选中的是 风扇
					{	
									if(status[2])                   //如果状态为1的  关掉小灯
								{
										status[2] = 0;
										HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
								}
								else{                              //为零的话 开灯
										status[2] = 1;
										HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET);       //开灯
								}
					}
		 }
		 for(int i = 0; i < 3; i++)
		 {
					if(i == flag)
					{
						Gui_DrawFont_GBK16(0,64 +i*16,YELLOW,BLACK,menu[i]);
					}
					else
					{
						Gui_DrawFont_GBK16(0,64 +i*16,BLACK,YELLOW,menu[i]);
					}
		 }
		sprintf(buf,"L1:%d L2:%d FA:%d",status[0],status[1],status[2]);      //显示一下设备状态
		Gui_DrawFont_GBK16(0,112,BLACK,YELLOW,(uint8_t *)buf);
 
	}
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Configure the main internal regulator output voltage 
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 16;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the peripherals clocks 
  */
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_ADC;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
  PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

int fputc(int ch, FILE *f)
{
	#if DEBUG_Printf
		HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 100);
	#endif
  return ch;
}


void Blink_Leds(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, uint8_t ms)
{
  HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_RESET);
  HAL_Delay(ms);
  HAL_GPIO_WritePin(GPIOx, GPIO_Pin, GPIO_PIN_SET);
  HAL_Delay(ms);
}

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
